using System.ComponentModel;

namespace Test.ConsoleProgram.Algorithm.Solution
{
    [TestDescription("算法: 0002. 两数相加")]
    public class No0002_AddTwoNumbers : AbsBaseTestItem
    {
        public override void OnTest()
        {
            Assert.TestExe((node) => ToStr(node),
                new ListNode(7) { next = new ListNode(0) { next = new ListNode(8) }, },
                answer: new string[] { "807" });

            Assert.TestExe(AddTwoNumbers,
                new ListNode(2) { next = new ListNode(4) { next = new ListNode(3) }, },
                new ListNode(5) { next = new ListNode(6) { next = new ListNode(4) }, },
                equalsMethod: (node1, node2) => ToStr(node1) == ToStr(node2),
                new ListNode(7) { next = new ListNode(0) { next = new ListNode(8) }, });

            Assert.TestExe(AddTwoNumbers,
                new ListNode(2) { next = new ListNode(4) { next = new ListNode(3) { next = new ListNode(3) }, }, },
                new ListNode(5) { next = new ListNode(6) { next = new ListNode(4) }, },
                equalsMethod: (node1, node2) => ToStr(node1) == ToStr(node2),
                new ListNode(7) { next = new ListNode(0) { next = new ListNode(8) { next = new ListNode(3) }, }, });

            Assert.TestExe(AddTwoNumbers,
                new ListNode(5),
                new ListNode(5),
                equalsMethod: (node1, node2) => ToStr(node1) == ToStr(node2),
                new ListNode(10));
        }

        private static string ToStr(ListNode node, string upperstr = "")
        {
            if (node == null)
            {
                return upperstr;
            }
            upperstr = node.val.ToString() + upperstr;
            return ToStr(node.next, upperstr);
        }
        public class ListNode
        {
            public int val;
            public ListNode next;
            public ListNode(int x) { val = x; }
        }
        public ListNode AddTwoNumbers(ListNode l1, ListNode l2)
        {
            ListNode value = null;
            ListNode trget = null;
            ListNode N1 = l1;
            ListNode N2 = l2;
            int redundancy = 0;
            while (N1 != null || N2 != null)
            {
                int iv = N1 != null ? N1.val : 0;
                iv += N2 != null ? N2.val : 0;
                iv += redundancy;
                if (iv >= 10)
                {
                    redundancy = 1;
                    iv -= 10;
                }
                else
                {
                    redundancy = 0;
                }
                N1 = N1 != null ? N1.next : null;
                N2 = N2 != null ? N2.next : null;

                ListNode calc_value = new ListNode(iv);
                if (redundancy == 1)
                {
                    calc_value.next = new ListNode(1);
                }
                if (value == null)
                {
                    value = calc_value;
                }
                else if (trget == null)
                {
                    trget = calc_value;
                    value.next = trget;
                }
                else
                {
                    trget.next = calc_value;
                    trget = trget.next;
                }
            }
            return value;
        }
    }
}
